ANDROID: usb: gadget: android_f_accessory: Add limits for descriptor size and device count

There is a possibility of the AOA‑HID registration command requesting a
report‑descriptor size of up to 0xFFFF and registering an unlimited
number of HID devices. In that situation the driver may keep calling
kzalloc(), and after enough repetitions the system can run out of memory
and trigger a kernel panic during HID registration.

* Enforce a maximum descriptor size (MAX_HID_DESC_SIZE = 4096) and
  require it to be > 0.
* Limit the number of concurrently registered AOA‑HID devices
  (MAX_HID_DEVICES = 32) and require the device ID to be > 0.
* Return –EINVAL for any request that violates these limits before any
  memory allocation is performed.

These checks prevent uncontrolled memory usage and keep the kernel
stable without changing the behaviour for valid callers.

Bug: 462321900
Change-Id: Ic847b76ce926e8e6ef800db6acee21ead9c7d0b0
Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
diff --git a/drivers/usb/gadget/function/android_f_accessory.c b/drivers/usb/gadget/function/android_f_accessory.c
index 0d096fa..a4446f4b 100644
--- a/drivers/usb/gadget/function/android_f_accessory.c
+++ b/drivers/usb/gadget/function/android_f_accessory.c
@@ -45,6 +45,12 @@
 #define TX_REQ_MAX 4
 #define RX_REQ_MAX 2
 
+/* Safe upper bound for a HID report descriptor*/
+#define MAX_HID_DESC_SIZE 4096
+
+/* Maximum number of concurrent AOA‑HID devices*/
+#define MAX_HID_DEVICES 32
+
 struct acc_hid_dev {
 	struct list_head list;
 	struct hid_device *hid;
@@ -596,8 +602,12 @@ static int acc_register_hid(struct acc_dev *dev, int id, int desc_length)
 	struct acc_hid_dev *hid;
 	unsigned long flags;
 
-	/* report descriptor length must be > 0 */
-	if (desc_length <= 0)
+	/*
+	 * Report descriptor length must be > 0 and not exceed the maximum size.
+	 * Device ID must be > 0 and within the allowed range.
+	 */
+	if (desc_length <= 0 || desc_length > MAX_HID_DESC_SIZE ||
+			id <= 0 || id > MAX_HID_DEVICES)
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev->lock, flags);